// Include standard headers
#include <stdio.h>
#include <stdlib.h>

// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <GL/glfw.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include "common/shader.hpp"

int main( void )
{
    
    if (!glfwInit())
    {
        /* code */
        fprintf(stderr, "%s\n", "fail to init GLFW");
    }
    
    glfwOpenWindowHint(GLFW_FSAA_SAMPLES,4);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR,2);
    
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR,1);

    if (!glfwOpenWindow(1024,678,0,0,0,0,32,0,GLFW_WINDOW))
    {
        fprintf(stderr, "%s\n", "fail to open glfw window");
        /* code */
        glfwTerminate();
        return -1;
    }
    //init glew
    if (glewInit() != GLEW_OK)
    {
        fprintf(stderr, "%s\n", "failed to init glew");
        return -1;
        /* code */
    }
    glfwSetWindowTitle("03");
    glfwEnable(GLFW_STICKY_KEYS);
    glClearColor(0.0f,0.0f,0.0f,0.0f);

    GLuint programID = LoadShaders( "SimpleTransform.vertexshader", "SingleColor.fragmentshader"  );
    
    GLuint MatrixID = glGetUniformLocation(programID,"MVP");

    GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");


    glm::mat4 Projection = glm::perspective(45.0f,4.0f/3.0f,0.1f,100.0f);
    glm::mat4 View = glm::lookAt(
            glm::vec3(4,3,3),
            glm::vec3(0,0,0),
            glm::vec3(0,1,0)
            );
    
    glm::mat4 Model = glm::mat4(1.0f);

    glm::mat4 MVP = Projection*View*Model;

    printf("%lu\n", MVP[0][0]);
    static const GLfloat g_vertex_buffer_data[] = { 

        -1.0f, -1.0f, 0.0f,

         1.0f, -1.0f, 0.0f,

         0.0f,  1.0f, 0.0f,

    };

    static const GLushort g_element_buffer_data[] = {0,1,2};



    GLuint vertexbuffer;

    glGenBuffers(1, &vertexbuffer);

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);



    do{



        // Clear the screen

        glClear( GL_COLOR_BUFFER_BIT );



        // Use our shader

        glUseProgram(programID);



        glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);

        // 1rst attribute buffer : vertices

        glEnableVertexAttribArray(vertexPosition_modelspaceID);

        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

        glVertexAttribPointer(

            vertexPosition_modelspaceID, // The attribute we want to configure

            3,                  // size

            GL_FLOAT,           // type

            GL_FALSE,           // normalized?

            0,                  // stride

            (void*)0            // array buffer offset

        );



        // Draw the triangle !

        glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle



        glDisableVertexAttribArray(vertexPosition_modelspaceID);



        // Swap buffers

        glfwSwapBuffers();



    } // Check if the ESC key was pressed or the window was closed

    while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&

           glfwGetWindowParam( GLFW_OPENED ) );



    // Close OpenGL window and terminate GLFW




    // Cleanup VBO

    glDeleteBuffers(1, &vertexbuffer);
    glDeleteProgram(programID);

    glfwTerminate();

	return 0;
}

